package com.zjj.algorithm.learning.leetcode.linkedlist;

/**
 * 24. 两两交换链表中的节点 中档题
 * 给你一个链表，两两交换其中相邻的节点，并返回交换后链表的头节点。
 * 你必须在不修改节点内部的值的情况下完成本题（即，只能进行节点交换）。
 * 输入：head = [1,2,3,4]
 * 输出：[2,1,4,3]
 * 示例 2：
 * <p>
 * 输入：head = []
 * 输出：[]
 * 示例 3：
 * <p>
 * 输入：head = [1]
 * 输出：[1]
 *
 * @author zjj_admin
 * @date 2022/11/21 10:39
 */
public class SwapNodesInPairs {

    public static void main(String[] args) {

        ListNode node6 = new ListNode(4, null);
        ListNode node7 = new ListNode(3, node6);
        ListNode node8 = new ListNode(2, node7);
        ListNode node9 = new ListNode(1, node8);
        swapPairs(node9);


    }

    /**
     * 时间
     * 0 ms
     * 击败
     * 100%
     * 内存
     * 38.9 MB
     * 击败
     * 86.63%
     *
     * @param head
     * @return
     */
    public static ListNode swapPairs(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        //添加一个头结点
        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode pre = dummy;
        ListNode curr = head;
        ListNode next = curr.next;
        while (true) {
            //交换curr和next的位置
            curr.next = curr.next.next;
            next.next = pre.next;
            pre.next = next;


            //让当前的curr变为pre
            pre = curr;
            //curr指向curr的下一个
            curr = pre.next;
            //只要方curr或者curr的下一个节点为 null 时，就可以退出了
            //因为当只有一个节点时就不需要交换了
            if (curr == null || curr.next == null) {
                break;
            }
            next = curr.next;

        }
        return dummy.next;
    }
}
